package com.zrwl.poscloud.core.restapi.file;


import com.zrwl.poscloud.base.entity.FileInfo;
import com.zrwl.poscloud.commons.config.file.FileConfig;
import com.zrwl.poscloud.commons.utils.FileUploadUtil;
import com.zrwl.poscloud.commons.utils.ResultUtil;
import com.zrwl.poscloud.commons.utils.tool.IpUtil;
import com.zrwl.poscloud.commons.vo.file.Chunk;
import com.zrwl.poscloud.xo.service.AccessManageService;
import com.zrwl.poscloud.xo.service.FileInfoService;
import com.zrwl.poscloud.xo.service.SyncService;
import com.zrwl.poscloud.xo.vo.FileInfoVO;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/fileUpload")
public class FileUploadApi {

    @Autowired
    FileInfoService fileInfoService;
    @Autowired
    FileConfig fileConfig;
    @Autowired
    AccessManageService accessManageService;
    @Autowired
    SyncService syncService;

    /***
     * 上传文件
     * @param request
     * @param type 文件类型：系统文件-软件更新相关（走分片的可能性大），内容管理（CMS）图片，商务产品等，用户-头像  --同步未测试
     * @return fileEntity
     */
    //单文件上传
    //http://localhost:8061/fileUpload/uploadFile
    @RequestMapping("/uploadFile")
    public String uploadFile(HttpServletRequest request,@RequestParam("type")int type,@RequestParam("ownerUid")String ownerUid,@RequestParam("ownerCode")String ownerCode, @RequestParam("file") MultipartFile file) {
        String ip = IpUtil.getIpAddress(request);
        accessManageService.enableAccess(ip);
        try {
            List<Map> list = FileUploadUtil.upload(request, fileConfig.fullFilePath(ownerCode, type));
            String fileName = String.valueOf(list.get(0).get("fileName"));
            long size = Long.parseLong(String.valueOf(list.get(0).get("size")));
            return ResultUtil.successWithData(syncService.uploadFile(fileName, type, ownerUid, ownerCode,size));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    @RequestMapping("/uploadQrCodeFile")
    public String uploadQrCodeFile(@RequestParam("type")int type,@RequestParam("ownerUid")String ownerUid,@RequestParam("ownerCode")String ownerCode, @RequestParam("file") MultipartFile file) {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress();
            accessManageService.enableAccess(ip);
            List<Map> list = FileUploadUtil.upload(file, fileConfig.fullFilePath(ownerCode, type));
            String fileName = String.valueOf(list.get(0).get("fileName"));
            long size = Long.parseLong(String.valueOf(list.get(0).get("size")));
            return ResultUtil.successWithData(syncService.uploadFile(fileName, type, ownerUid, ownerCode,size));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //多文件上传 --同步未测试
    @RequestMapping("/uploadFiles")
    public String uploadFiles(HttpServletRequest request, int type, String ownerUid, String ownerCode, @RequestParam("files") List<MultipartFile> files) {
        String ip = IpUtil.getIpAddress(request);
        accessManageService.enableAccess(ip);
        try {
            List<Map> list = FileUploadUtil.upload(request, fileConfig.fullFilePath(ownerCode, type));
            return ResultUtil.successWithData(syncService.uploadFiles(type, ownerUid, ownerCode, list));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /***
     * 上传文件（分片上传） -- 未测试
     * @param request
     * @return
     */
    @PostMapping(value = "/uploadByChunk")
    public String uploadByChunk(HttpServletRequest request, Chunk chunk) {
        String ip = IpUtil.getIpAddress(request);
        Integer chunkNumber = chunk.getChunkNumber();
        accessManageService.enableAccess(ip);
        String fileHeadPath = fileConfig.fullFilePath("", 99);
        String fileFullPath = fileHeadPath + File.separator + chunk.getIdentifier();
        File path = new File(fileFullPath);
        if (!path.exists())
            if (!path.mkdirs())
                throw new RuntimeException("创建路径失败");
        //分片上传
//        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        boolean isMultipart = true;
        if (isMultipart) {
            MultipartFile file = chunk.getFile();
            if (file == null) {
                throw new RuntimeException("文件为空");
            }
            if (chunkNumber == null) {
                chunkNumber = 0;
            }
            File outFile = new File(fileFullPath, chunkNumber + ".part");
            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
                FileUtils.copyInputStreamToFile(inputStream, outFile);
            } catch (IOException e) {
                e.printStackTrace();
                ResultUtil.errorWithMessage("部分" + chunkNumber + "上传失败" + e.getMessage());
            }
        }
        return ResultUtil.successWithMessage("部分" + chunkNumber + "上传成功");

    }

    /***
     * 合并分片的文件 -- 未测试
     * @return
     * @throws Exception
     */
    @RequestMapping("/mergeFileForChunk")
    public String mergeFileForChunk(String identifier, String fileName, String ownerCode, int type) {
        //从文件信息获取文件分块路径也是合并路径
        String fileHeadPath = fileConfig.fullFilePath("", type);
        String filePartFullPath = fileHeadPath + File.separator + identifier;
        FileInfoVO fileInfoVO = new FileInfoVO();
        fileInfoVO.setFileInfoType(type);
        fileInfoVO.setFileInfoName(fileName);
        fileInfoVO.setOwnerCode(ownerCode);
//        fileInfoVO.setFileInfoSize(fileSize);//
        FileInfo entity = fileInfoService.addFile(fileInfoVO);
        String fileDiskName = entity.getCode() + entity.getFileName().substring(entity.getFileName().indexOf("."));
        String fileFullPath = fileConfig.fullFilePath(ownerCode, type);
        //合并文件
        try {
            //分片的文件夹
            File partFilePath = new File(filePartFullPath);
            if (partFilePath.isDirectory()) {
                File fullFile = new File(fileFullPath + File.separator + fileDiskName);
                if (fullFile.exists()) {
                    fullFile.delete();
                }
                fullFile.createNewFile();
                File[] partFiles = partFilePath.listFiles();
                if (partFiles != null && partFiles.length > 0) {
                    for (int i = 1; i <= partFiles.length; i++) {
                        File s = new File(fileFullPath + File.separator + identifier, i + ".part");
                        FileOutputStream destTempfos = new FileOutputStream(fullFile, true);
                        FileUtils.copyFile(s, destTempfos);
                        destTempfos.close();
                    }
                }
            }
            FileUtils.deleteDirectory(partFilePath);
        } catch (IOException e) {
            e.printStackTrace();
            ResultUtil.errorWithMessage("合并失败" + e.getMessage());
        }
        entity.setStatus(FileConfig.FileStatusEnums.normal.status);
        entity.updateById();
        return ResultUtil.successWithMessage("合并成功");
    }

    /**
     * ckeditor 上传文件
     * @param request
     * @return
     */
    @RequestMapping(value = "/ckeditorUploadFile", method = RequestMethod.POST)
    public String ckeditorUploadFile(HttpServletRequest request) {
        int type = Integer.parseInt(request.getParameter("type"));
        String ownerUid = request.getParameter("ownerUid");
        String ownerCode = request.getParameter("ownerCode");
        String ip = IpUtil.getIpAddress(request);
        accessManageService.enableAccess(ip);
        try {
            List<Map> list = FileUploadUtil.upload(request, fileConfig.fullFilePath(ownerCode, type));
            String fileName = String.valueOf(list.get(0).get("fileName"));
            long size = Long.parseLong(String.valueOf(list.get(0).get("size")));
            return ResultUtil.successWithData(syncService.uploadFile(fileName, type, ownerUid, ownerCode,size));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
